﻿using System.Collections.Generic;
using System.IO;
using System.Xml.Linq;
using iTextSharp.text;
using iTextSharp.text.pdf;

namespace PocoReport
{
    public class Report
    {
        public Style Style { get; set; }
        public Section Header { get; protected set; }
        public Section Body { get; protected set; }
        public Section Footer { get; protected set; }

        public Report()
        {
            Header = new Section();
            Body = new Section();
            Footer = new Section();
            Style = new Style();
        }

        public void Load(string fileName)
        {
            using(FileStream stream = File.OpenRead(fileName))
            {
                Load(stream);
            }
        }

        public void Load(Stream stream)
        {
            XDocument document = XDocument.Load(new StreamReader(stream));
            Style = new Style(document.Root);
            Header = new Section();
            Header.Load(document.Root.Element("Header"));
            Body = new Section();
            Body.Load(document.Root.Element("Body"));
            Footer = new Section();
            Footer.Load(document.Root.Element("Footer"));
        }

        public void Generate(Stream stream, Dictionary<string, object> dataSource)
        {
            Scope scope = new Scope(dataSource);

            Document document = new Document();
            PdfWriter.GetInstance(document, stream);
            document.Open();
            try
            {
                document.Add(Header.GetPdfElement(document, Style, scope));
                document.Add(Body.GetPdfElement(document, Style, scope));
                document.Add(Footer.GetPdfElement(document, Style, scope));
            }
            finally
            {
                document.Close();
            }
        }

        public void Save(Stream stream)
        {
            using(StreamWriter writer = new StreamWriter(stream))
            {
                Save(writer);
            }
        }

        public void Save(TextWriter writer)
        {
            XElement reportElement = new XElement("Report");            
            reportElement.SetAttribValue("Style", Style);
            SaveSection(reportElement, Header, "Header");
            SaveSection(reportElement, Body, "Body");
            SaveSection(reportElement, Footer, "Footer");

            XDocument document = new XDocument();
            document.Add(reportElement);
            document.Save(writer);
        }

        private void SaveSection(XElement reportElement, Section section, string tagName)
        {
            XElement element = (XElement) section.Save();
            element.Name = tagName;
            reportElement.Add(element);
        }
    }

}
